'''
WGS84-->墨卡托坐标-->像素坐标-->瓦片坐标
'''

import math
from pyproj import CRS
from pyproj import Transformer
from pyproj import _datadir, datadir


crs_WGS84 = CRS.from_epsg(4326)  # WGS84地理坐标系
crs_WebMercator = CRS.from_epsg(3857)  # Web墨卡托投影坐标系
cell_size = 0.009330691929342804  # 分辨率（米），一个像素表示的大小(24级瓦片)
origin_level = 24  # 原始瓦片级别
EarthRadius = 6378137.0  # 地球半径
tile_size = 256  # 瓦片大小
crs_WGS84 = CRS.from_epsg(4326)  # WGS84地理坐标系
crs_WebMercator = CRS.from_epsg(3857)  # Web墨卡托投影坐标系
cell_size = 0.009330691929342804  # 分辨率（米），一个像素表示的大小(24级瓦片)
origin_level = 24  # 原始瓦片级别
EarthRadius = 6378137.0  # 地球半径
tile_size = 256  # 瓦片大小


def WGS84ToWebMercator_Single(lat, lon):
    """
    WGS84坐标转web墨卡托坐标
    :param lat:  WGS84坐标纬度
    :param lon:  WGS84坐标经度
    :return:  web墨卡托坐标x,y
    """
    transformer = Transformer.from_crs(crs_WGS84, crs_WebMercator)
    x, y = transformer.transform(lat, lon)
    return [x, y]


def Web_to_Pixel(x, y, level):
    """
    Web墨卡托坐标转像素坐标
    :param x: Web墨卡托坐标x值
    :param y: Web墨卡托坐标y值
    :param level: 瓦片级别
    :return: 像素坐标
    """
    real_cell_size = cell_size * math.pow(2, (origin_level - level))
    pixel_x = math.floor((x + math.pi * EarthRadius) / real_cell_size)
    pixel_y = math.floor((math.pi * EarthRadius - y) / real_cell_size)
    return [pixel_x, pixel_y]


def GetTileByPixel(px, py):
    """
    计算像素所在的瓦片号
    :param px py: 像素坐标
    :return: 瓦片行列号
    """
    tile_x = int(px / tile_size)
    tile_y = int(py / tile_size)
    return [tile_x, tile_y]


def GetTileByPixelAndTitle(p, t):
    """
    计算像素值,针对该瓦片左上角
    p,像素坐标,针对指定级别拼成的瓦片
    t,该瓦片坐标(横纵的个数)
    return 该点的像素值,以该瓦片左上角为参照
    """
    tx2 = p[0]-t[0]*tile_size
    ty2 = p[1]-t[1]*tile_size
    return [tx2, ty2]


def WGS84ToPixel(lon, lat):
    # WGS84-->墨卡托坐标
    [x, y] = WGS84ToWebMercator_Single(lat, lon)

    # 墨卡托坐标-->像素坐标,
    # 这个像素感觉像是根据最深级别拼成一张大图,计算的像素坐标,并不是针对指定级别瓦片(左上角)
    [px, py] = Web_to_Pixel(x, y, 24)

    # 通过像素坐标-->瓦片坐标(文件)
    [tx, ty] = GetTileByPixel(px, py)

    # 获取像素,以该瓦片左上角为原点
    [px2, px2] = GetTileByPixelAndTitle([px, py], [tx, ty])

    obj = {
        'title': [tx, ty],
        'pixel': [px2, px2]
    }

    return obj


if __name__ == "__main__":
    px_py = WGS84ToPixel(110, 50)
    print(px_py)
